unit unitPaintbox;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  ExtCtrls, StdCtrls, ObjectInspector, PropEdits, TypInfo,uniticons;

type

  { TForm1 }

  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    ScrollBox1: TScrollBox;
    PropertyGrid: TOIPropertyGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure PaintBox1DblClick(Sender: TObject);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    function DrawAllIcons(X,Y:Integer): Boolean; //retorna true se tiver algum conflito
    { private declarations }
  public
    MethodCokb3d: Array[1..10] of Cokb3d;
    MethodAddCoord: Array[1..10] of AddCoord;
    TheObjectInspector : TObjectInspectorDlg;
    ThePropertyEditorHook: TPropertyEditorHook;
    procedure SetObjectInspectorRoot(AComponent: TComponent);
    { public declarations }
  end;

  const IconSize:Integer = 13;
    LabelIconSize:Integer = 11; //Tamanho da fonte da label do ícone

var
  Form1: TForm1;

  IconsNumber:Integer; //Numero de icones no paintbox

  MousePosX: Integer;  //posicao do mouse
  MousePosY:Integer;  //substituir por ponteiros

  Cokb3dNumber: Integer; // numero de cokb3d criados
  AddCoordNumber: Integer;

  Icons: Array[1..10] of TIcon;

implementation
uses unitmessages, unittextfiles;
{$R *.lfm}

{ TForm1 }

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Form2.MethodClicked then
  begin
    DrawAllIcons(X,Y);
    Canvas.Rectangle(X-IconSize, Y-IconSize, X+IconSize, Y+IconSize);
    Canvas.TextOut(X - (Trunc(Canvas.TextWidth(Form2.SelectedIcon)/2)),
      Y + Iconsize, Form2.SelectedIcon);
  end
  else
  begin
    //DrawAllIcons(X,Y);
  end;
  //FormMessages.Memo1.Append('X: '+IntToStr(x)+'  Y: '+IntToStr(y));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IconsNumber:=0;{
  Canvas.Font.Size:= LabelIconSize;
  Canvas.Font.Color:=clBlack;}
  ThePropertyEditorHook:= TPropertyEditorHook.Create;
  TheObjectInspector:= TObjectInspectorDlg.Create(Application);
  TheObjectInspector.PropertyEditorHook:= ThePropertyEditorHook;
  TheObjectInspector.SetBounds(10, 10, 240, 500);
  PropertyGrid:= TOIPropertyGrid.CreateWithParams(self, ThePropertyEditorHook,
    [tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkSet{, tkMethod}
      , tkSString, tkLString, tkAString, tkWString, tkVariant
      , tkArray, tkRecord, tkInterface, tkClass, tkObject, tkWChar, tkBool
      , tkInt64, tkQWord], 25);
  TheObjectInspector.Show;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var I:Integer;
begin
  ThePropertyEditorHook.Free;
//destruir TIcon
//destruir TMethod
end;

procedure TForm1.PaintBox1DblClick(Sender: TObject);
var I,J:Integer;  Found:Boolean;
begin
  Found:=False;
  I:=1;
  While not Found do //for I:=1 to IconsNumber do
  begin
    if I >= IconsNumber then Found:=True;
    if (MousePosX - (Icons[I].PosX - IconSize) >= 0 ) and
        (MousePosX - (Icons[I].PosX - IconSize)  <= IconSize*2)  then
    begin
      if (MousePosY - (Icons[I].PosY - IconSize) >= 0 ) and
        (MousePosY - (Icons[I].PosY - IconSize)  <= IconSize*2)  then
      begin
        Found:=True;
        if Icons[I].IconType = 'kringing' then
        begin
          //FormMessages.Memo1.Append('Found = True');
        end;
        if Icons[I].IconType = 'cokb3d' then
        begin
          for J:=1 to Cokb3dNumber do
          begin
            if (MousePosX - (MethodCokb3d[J].PosX - IconSize) >= 0 ) and
              (MousePosX - (MethodCokb3d[J].PosX - IconSize)  <= IconSize*2)  then
            begin
              if (MousePosY - (MethodCokb3d[J].PosY - IconSize) >= 0 ) and
                (MousePosY - (MethodCokb3d[J].PosY - IconSize)  <= IconSize*2)
                  then
              begin
                SetObjectInspectorRoot(MethodCokb3d[J]);
              end;
            end;
          end;
        end
        else
        if Icons[I].IconType = 'addcoord' then
        begin
          for J:=1 to Cokb3dNumber do
          begin
            if (MousePosX - (MethodAddCoord[J].PosX - IconSize) >= 0 ) and
              (MousePosX - (MethodAddCoord[J].PosX - IconSize)  <= IconSize*2)  then
            begin
              if (MousePosY - (MethodAddCoord[J].PosY - IconSize) >= 0 ) and
                (MousePosY - (MethodAddCoord[J].PosY - IconSize)  <= IconSize*2)
                  then
              begin
                SetObjectInspectorRoot(MethodAddCoord[J]);
              end;
            end;
          end;
        end;
      end;
    end;
    Inc(I);
  end;
end;

procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Form2.MethodClicked then
  begin
    //if not OverrideIcon then
    Inc(IconsNumber);
    Icons[IconsNumber]:= TIcon.Create;
    Icons[IconsNumber].IconIndex:= IconsNumber;
    Icons[IconsNumber].IconType:= Form2.SelectedIcon;
    Icons[IconsNumber].PosX:= X;
    Icons[IconsNumber].PosY:= Y;
    Icons[IconsNumber].IconType:= Form2.SelectedIcon;

    if Form2.SelectedIcon = 'cokb3d' then
    begin
      Inc(Cokb3dNumber);
      MethodCokb3d[Cokb3dNumber] := Cokb3d.Create(nil);
      Icons[IconsNumber].IconTypeNumber:=Cokb3dNumber;
      SetObjectInspectorRoot(MethodCokb3d[Cokb3dNumber]);
      MethodCokb3d[Cokb3dNumber].IconIndex:= IconsNumber;
      MethodCokb3d[Cokb3dNumber].PosX:=X;
      MethodCokb3d[Cokb3dNumber].PosY:=Y;
    end
    else
    if Form2.SelectedIcon = 'addcoord' then
    begin
      Inc(AddCoordNumber);
      MethodAddCoord[AddCoordNumber]:= AddCoord.Create(nil);
      Icons[IconsNumber].IconTypeNumber:=AddCoordNumber;
      SetObjectInspectorRoot(MethodAddCoord[AddCoordNumber]);
      MethodAddCoord[AddCoordNumber].IconIndex:= IconsNumber;
      MethodAddCoord[AddCoordNumber].PosX:= X;
      MethodAddCoord[AddCoordNumber].PosY:= Y;
    end;
    Form2.MethodClicked:= False;
  end
  else
  begin
    //mostra as propriedades no objectinspector
    //colocar aqui tbm ou apenas no dbl click?
  end;
  MousePosX:=X;
  MousePosY:=Y;
  //FormMessages.Memo1.Append('X: '+IntToStr(X)  +'   Y: '+IntToStr(Y));
end;

function TForm1.DrawAllIcons(X, Y:Integer): Boolean;

  procedure Arrow(ArrowType:String; Xi,Yi, Xf, Yf:Integer);
  begin
    //arrowtype = input, output //cores diferentes
    Canvas.Line(Xi+Trunc(IconSize/2), Yi+Trunc(IconSize/2),
      Xf+Trunc(Iconsize/2), Yf+Trunc(Iconsize/2));
  end;

var I: Integer;  NameTemp: String;
begin
  Canvas.Clear;
  for I:= 1 to IconsNumber do
  begin
    Canvas.Rectangle(Icons[I].PosX-IconSize, Icons[I].PosY-IconSize,
      Icons[I].PosX+IconSize, Icons[I].PosY+IconSize);

    if Icons[I].IconType = 'cokb3d' then
    begin
      NameTemp:=MethodCokb3d[Icons[I].IconTypeNumber].VarName;
    end
    else
    if Icons[I].IconType = 'addcoord' then
    begin
      NameTemp:=MethodAddCoord[Icons[I].IconTypeNumber].VarName;
    end;

    if NameTemp = EmptyStr then
      Canvas.TextOut(Icons[I].PosX - (Trunc(Canvas.TextWidth(Icons[I].IconType)/2)),
        Icons[I].PosY+Iconsize, Icons[I].IconType)
    else
      Canvas.TextOut(Icons[I].PosX - (Trunc(Canvas.TextWidth(NameTemp)/2)),
        Icons[I].PosY+Iconsize, NameTemp);
    if Icons[I].Input1 > 0 then
    begin
      Arrow('input', Icons[I].PosX, Icons[I].PosY, Icons[Icons[I].Input1].PosX,
        Icons[Icons[I].Input1].PosY);
    end;
    if Icons[I].Output1 > 0 then
    begin
      Arrow('output', Icons[I].PosX, Icons[I].PosY, Icons[Icons[I].Output1].PosX,
        Icons[Icons[I].Output1].PosY);
    end;
    //DrawIcon; procedure que desenha a imagem do icone
  end;
  Result:=False;
end;

procedure TForm1.SetObjectInspectorRoot(AComponent: TComponent);
var Selection: TPersistentSelectionList;
begin
  ThePropertyEditorHook.LookupRoot:= AComponent;
  Selection:= TPersistentSelectionList.Create;
  Selection.Add(AComponent);
  TheObjectInspector.Selection:= Selection;
  PropertyGrid.Selection:= Selection;
  Selection.Free;
end;

end.
